OK, Mottram warned me.
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 6 Oct 2002 04:09:37 +0000 (04:09 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 6 Oct 2002 04:09:37 +0000 (04:09 +0000)
Copy cdata coming in and handle it in the end tage beause of bad
expat design.  (grrr)

gpsbabel/geo.c
gpsbabel/gpx.c
gpsbabel/reference/gl.loc

index db6deb3b7ac3eb9b9f141e0817be21252ba10cc9..8b0e9fc3bfca1c177fdfea962cd397e0206c390f 100644 (file)
@@ -22,6 +22,8 @@
 static int in_wpt;
 static int in_name;
 static int in_link;
+static int in_cdata;
+static char *cdatastr;
 
 static XML_Parser psr;
 static waypoint *wpt_tmp;
@@ -30,6 +32,7 @@ FILE *fd;
 FILE *ofd;
 
 #define MYNAME "geo"
+#define MY_CBUF 4096
 
 static void
 tag_coord(const char **attrv)
@@ -104,6 +107,16 @@ geo_start(void *data, const char *el, const char **attr)
 static void
 geo_end(void *data, const char *el)
 {
+       if (in_cdata) {
+               if (in_name) {
+                       wpt_tmp->description = xstrdup(cdatastr);
+               }
+               if (in_link) {
+                       wpt_tmp->url = xstrdup(cdatastr);
+               }
+               in_cdata--;
+               memset(cdatastr,0, MY_CBUF);
+       }
        if (strcmp(el, "waypoint") == 0) {
                waypt_add(wpt_tmp);
                in_wpt--;
@@ -119,18 +132,11 @@ geo_end(void *data, const char *el)
 static void
 geo_cdata(void *dta, const XML_Char *s, int len)
 {
-       char *foo = xmalloc(len+1);
-       foo[len] = 0;
-       strncpy(foo, s, len);
-       if (in_name) {
-               wpt_tmp->description = foo;
-       }
-       if (in_link) {
-               wpt_tmp->url = foo;
-       }
+       char *estr = cdatastr + strlen(cdatastr);
+       memcpy(estr, s, len); 
+       in_cdata++;
 }
 
-
 void
 geo_rd_init(const char *fname)
 {
@@ -145,6 +151,7 @@ geo_rd_init(const char *fname)
        }
 
        XML_SetElementHandler(psr, geo_start, geo_end);
+       cdatastr = xcalloc(MY_CBUF,1);
        XML_SetCharacterDataHandler(psr, geo_cdata);
 }
 
@@ -173,7 +180,7 @@ void
 geo_read(void)
 {
        int len;
-       char buf[1024];
+       char buf[MY_CBUF];
        
        while ((len = fread(buf, 1, sizeof(buf), fd))) {
                if (!XML_Parse(psr, buf, len, feof(fd))) {
@@ -182,7 +189,8 @@ geo_read(void)
                                XML_ErrorString(XML_GetErrorCode(psr)));
                }
        }
-       
+
+       XML_ParserFree(psr);
 }
 
 static void
index ce7ad7442ea79242939301140fbe143af6089561..7ef7c96953a00e16c37a6cae16e55104530b5984 100644 (file)
@@ -28,6 +28,8 @@ static int in_ele;
 static int in_name;
 static int in_time;
 static int in_desc;
+static int in_cdata;
+static char *cdatastr;
 
 static XML_Parser psr;
 
@@ -39,6 +41,7 @@ static FILE *fd;
 static FILE *ofd;
 
 #define MYNAME "GPX"
+#define MY_CBUF 4096
 
 static void
 tag_gpx(const char **attrv)
@@ -101,6 +104,34 @@ gpx_start(void *data, const char *el, const char **attr)
 static void
 gpx_end(void *data, const char *el)
 {
+       if (in_cdata) {
+               if (in_name && in_wpt) {
+                       wpt_tmp->shortname = xstrdup(cdatastr);
+               }
+               if (in_desc && in_wpt) {
+                       wpt_tmp->description = xstrdup(cdatastr);
+               }
+               if (in_ele) {
+                       sscanf(cdatastr, "%lf", 
+                               &wpt_tmp->position.altitude.altitude_meters);
+               }
+               if (in_time && (in_wpt || in_rte)) {
+                       struct tm tm;
+                       sscanf(cdatastr, "%d-%d-%dT%d:%d:%dZ\n", 
+                               &tm.tm_year,
+                               &tm.tm_mon,
+                               &tm.tm_mday,
+                               &tm.tm_hour,
+                               &tm.tm_min,
+                               &tm.tm_sec);
+                       tm.tm_mon -= 1;
+                       tm.tm_year -= 1900;
+                       tm.tm_isdst = 1;
+                       wpt_tmp->creation_time = mktime(&tm);
+               }
+               in_cdata--;
+               memset(cdatastr, 0, MY_CBUF);
+       }
        if (strcmp(el, "wpt") == 0) {
                waypt_add(wpt_tmp);
                in_wpt--;
@@ -122,32 +153,19 @@ gpx_end(void *data, const char *el)
 static void
 gpx_cdata(void *dta, const XML_Char *s, int len)
 {
-       char *foo = xmalloc(len+1);
-       foo[len] = 0;
-       strncpy(foo, s, len);
-       if (in_name && in_wpt) {
-               wpt_tmp->shortname = foo;
-       }
-       if (in_desc && in_wpt) {
-               wpt_tmp->description = foo;
-       }
-       if (in_ele) {
-               sscanf(foo, "%lf", 
-                       &wpt_tmp->position.altitude.altitude_meters);
-       }
-       if (in_time && (in_wpt || in_rte)) {
-               struct tm tm;
-               sscanf(foo, "%d-%d-%dT%d:%d:%dZ\n", 
-                       &tm.tm_year,
-                       &tm.tm_mon,
-                       &tm.tm_mday,
-                       &tm.tm_hour,
-                       &tm.tm_min,
-                       &tm.tm_sec);
-               tm.tm_mon -= 1;
-               tm.tm_year -= 1900;
-               tm.tm_isdst = 1;
-               wpt_tmp->creation_time = mktime(&tm);
+       char *estr;
+
+       /*
+        * I'm exceedingly unamused that libexpat makes me keep all this
+        * horrible state just I can concatenate buffers that it hands
+        * me as a cdata that are fragmented becuae they span a read.  Grrr.
+        */
+
+       if ((in_name && in_wpt) || (in_desc && in_wpt) || (in_ele) || 
+                       (in_time && (in_wpt || in_rte)))  {
+               estr = cdatastr + strlen(cdatastr);
+               memcpy(estr, s, len);
+               in_cdata++;
        }
 }
 
@@ -162,6 +180,7 @@ gpx_rd_init(const char *fname)
        if (!psr) {
                fatal(MYNAME ": Cannot create XML Parser\n");
        }
+       cdatastr = xcalloc(MY_CBUF, 1);
        XML_SetElementHandler(psr, gpx_start, gpx_end);
        XML_SetCharacterDataHandler(psr, gpx_cdata);
 }
@@ -191,7 +210,7 @@ gpx_read(void)
 {
        int len;
        int done = 0;
-       char buf[102400];
+       char buf[MY_CBUF];
 
        while (!done) {
                len = fread(buf, 1, sizeof(buf), fd);
index 518337cca858ed8b448ca0c53d6edb7306f410e5..ff5fba8c930ac9ee692f8ffbf0ef4cf65fbfa290 100644 (file)
@@ -17,7 +17,7 @@
 <waypoint>
 <name id="GC25A9"><![CDATA[FOSTER by JoGPS & Family]]></name>
 <coord lat="36.038483" lon="-86.648617"></coord>
-<link text ="Cache Details">D=9641</link>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=9641</link>
 </waypoint>
 <waypoint>
 <name id="GC2723"><![CDATA[Logan Lighthouse by JoGps & Family]]></name>